package edu.bu.cs673.superkids123.parents.view;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextArea;
import javax.swing.JTextField;

import edu.bu.cs673.superkids123.AbstractFrame;
import edu.bu.cs673.superkids123.AbstractNavigationView;
import edu.bu.cs673.superkids123.common.model.Parent;
import edu.bu.cs673.superkids123.parents.controller.CreateParentController;
import edu.bu.cs673.superkids123.parents.helper.Constants;

/**
 * 
 * 
 * @author bhepburn
 * 
 */
public class CreateParentView extends AbstractNavigationView implements
		KeyListener, ActionListener {
	private JTextField nameField, emailField;
	private JPasswordField pwdField, pwdConfirmField;
	private JButton createBtn;
	private JLabel errorMessage;

	// Start with false as these will be empty
	private boolean userNamePassed = false, pwdPassed = false,
			emailPassed = false;
	private Pattern emailPattern;

	private Parent currentParent = null;

	public CreateParentView(AbstractFrame mainFrame) {
		super(mainFrame);
		emailPattern = Pattern.compile(Constants.EMAIL_REGEX);
	}

	/**
	 * @wbp.parser.entryPoint
	 */
	@Override
	protected JPanel layout() {
		currentParent = getMainFrame().getController(
				CreateParentController.class).current();

		userNamePassed = pwdPassed = emailPassed = currentParent != null;

		JPanel userInfo = new JPanel(new GridBagLayout());
		GridBagLayout gblUserInfo = new GridBagLayout();
		gblUserInfo.columnWidths = new int[] { 75, 100, 20, 300, 75 };
		gblUserInfo.rowHeights = new int[] { 50, 50, 50, 50, 50, 50 };
		userInfo.setLayout(gblUserInfo);

		JTextArea infoMsg = new JTextArea();
		infoMsg.setWrapStyleWord(true);
		infoMsg.setLineWrap(true);
		infoMsg.setFont(new Font("Comic Sans MS", Font.BOLD, 16));
		infoMsg.setEditable(false);
		infoMsg.setBackground(userInfo.getBackground());

		if (currentParent != null) {
			infoMsg.setText("Update your information and then hit save:");
		} else if (authController.areParentsInitialized()) {
			infoMsg.setText("Enter the following information to create another parent account:");
		} else {
			infoMsg.setText("Before your child can start the adventure you must create an account to manage settings:");
		}

		GridBagConstraints gbcInfoMsg = new GridBagConstraints();
		gbcInfoMsg.insets = new Insets(0, 0, 5, 5);
		gbcInfoMsg.gridx = 0;
		gbcInfoMsg.gridy = 0;
		gbcInfoMsg.gridwidth = 5;
		gbcInfoMsg.fill = GridBagConstraints.HORIZONTAL;
		userInfo.add(infoMsg, gbcInfoMsg);

		JLabel nameLabel = new JLabel("User's Name:");
		nameLabel.setFont(new Font("Comic Sans MS", Font.BOLD, 16));
		GridBagConstraints gbcNameLabel = new GridBagConstraints();
		gbcNameLabel.insets = new Insets(0, 0, 5, 5);
		gbcNameLabel.anchor = GridBagConstraints.EAST;
		gbcNameLabel.gridx = 1;
		gbcNameLabel.gridy = 1;
		userInfo.add(nameLabel, gbcNameLabel);

		nameField = new JTextField();
		if (currentParent != null)
			nameField.setText(currentParent.getName());
		nameLabel.setLabelFor(nameField);
		nameField.setFont(new Font("Comic Sans MS", Font.BOLD, 16));
		nameField.addKeyListener(this);
		GridBagConstraints gbc_textField = new GridBagConstraints();
		gbc_textField.fill = GridBagConstraints.HORIZONTAL;
		gbc_textField.insets = new Insets(0, 0, 5, 0);
		gbc_textField.gridx = 3;
		gbc_textField.gridy = 1;
		userInfo.add(nameField, gbc_textField);
		nameField.setColumns(10);

		JLabel pwdLabel = new JLabel("Password:");
		pwdLabel.setFont(new Font("Comic Sans MS", Font.BOLD, 16));
		GridBagConstraints gbcpwdLabel = new GridBagConstraints();
		gbcpwdLabel.insets = new Insets(0, 0, 5, 5);
		gbcpwdLabel.anchor = GridBagConstraints.EAST;
		gbcpwdLabel.gridx = 1;
		gbcpwdLabel.gridy = 2;
		userInfo.add(pwdLabel, gbcpwdLabel);

		pwdField = new JPasswordField();
		if (currentParent != null)
			pwdField.setText(currentParent.getClearPassword());
		pwdLabel.setLabelFor(pwdField);
		pwdField.setFont(new Font("Comic Sans MS", Font.BOLD, 16));
		pwdField.addKeyListener(this);
		GridBagConstraints gbcpwdField = new GridBagConstraints();
		gbcpwdField.fill = GridBagConstraints.HORIZONTAL;
		gbcpwdField.insets = new Insets(0, 0, 5, 0);
		gbcpwdField.gridx = 3;
		gbcpwdField.gridy = 2;
		userInfo.add(pwdField, gbcpwdField);

		JLabel pwdConfirmLabel = new JLabel("Confirm Password:");
		pwdConfirmLabel.setFont(new Font("Comic Sans MS", Font.BOLD, 16));
		GridBagConstraints gbcpwdConfirmLabel = new GridBagConstraints();
		gbcpwdConfirmLabel.insets = new Insets(0, 0, 5, 5);
		gbcpwdConfirmLabel.anchor = GridBagConstraints.EAST;
		gbcpwdConfirmLabel.gridx = 1;
		gbcpwdConfirmLabel.gridy = 3;
		userInfo.add(pwdConfirmLabel, gbcpwdConfirmLabel);

		pwdConfirmField = new JPasswordField();
		if (currentParent != null)
			pwdConfirmField.setText(currentParent.getClearPassword());
		pwdConfirmLabel.setLabelFor(pwdConfirmField);
		pwdConfirmField.setFont(new Font("Comic Sans MS", Font.BOLD, 16));
		pwdConfirmField.addKeyListener(this);
		GridBagConstraints gbcpwdConfirmField = new GridBagConstraints();
		gbcpwdConfirmField.fill = GridBagConstraints.HORIZONTAL;
		gbcpwdConfirmField.insets = new Insets(0, 0, 5, 0);
		gbcpwdConfirmField.gridx = 3;
		gbcpwdConfirmField.gridy = 3;
		userInfo.add(pwdConfirmField, gbcpwdConfirmField);

		JLabel emailLabel = new JLabel("Email Address:");
		emailLabel.setLabelFor(pwdConfirmField);
		emailLabel.setFont(new Font("Comic Sans MS", Font.BOLD, 16));
		GridBagConstraints gbcEmailLabel = new GridBagConstraints();
		gbcEmailLabel.anchor = GridBagConstraints.EAST;
		gbcEmailLabel.insets = new Insets(0, 0, 5, 5);
		gbcEmailLabel.gridx = 1;
		gbcEmailLabel.gridy = 4;
		userInfo.add(emailLabel, gbcEmailLabel);

		emailField = new JTextField();
		if (currentParent != null)
			emailField.setText(currentParent.getEmail());
		emailField.setFont(new Font("Comic Sans MS", Font.BOLD, 16));
		emailField.addKeyListener(this);

		GridBagConstraints gbcEmailField = new GridBagConstraints();
		gbcEmailField.fill = GridBagConstraints.HORIZONTAL;
		gbcEmailField.insets = new Insets(0, 0, 5, 0);
		gbcEmailField.insets = new Insets(0, 0, 5, 0);
		gbcEmailField.gridx = 3;
		gbcEmailField.gridy = 4;
		userInfo.add(emailField, gbcEmailField);

		JPanel createPanel = new JPanel(new BorderLayout());
		createBtn = new JButton("Create");
		if (currentParent != null)
			createBtn.setText("Save");
		createBtn.setEnabled(false);
		if (currentParent != null)
			createBtn.setEnabled(true);
		createBtn.addActionListener(this);
		createPanel.add(createBtn, BorderLayout.EAST);

		errorMessage = new JLabel("");
		errorMessage.setForeground(Color.RED);
		createPanel.add(errorMessage, BorderLayout.WEST);

		GridBagConstraints gbcCreatePanel = new GridBagConstraints();
		gbcCreatePanel.anchor = GridBagConstraints.EAST;
		gbcCreatePanel.gridx = 3;
		gbcCreatePanel.gridy = 5;
		userInfo.add(createPanel, gbcCreatePanel);

		return userInfo;
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		Object source = e.getSource();
		if (source.equals(createBtn)) {
			Parent parent = (currentParent != null) ? currentParent : new Parent();
			parent.setName(nameField.getText());
			parent.setPassword(new String(pwdField.getPassword()));
			parent.setEmail(emailField.getText());

			if (currentParent != null)
				getMainFrame().getController(CreateParentController.class)
						.updateParent(parent);
			else
				getMainFrame().getController(CreateParentController.class)
						.createParent(parent);
		}
	}

	@Override
	public void keyPressed(KeyEvent e) {
		// Ignore this

	}

	@Override
	public void keyReleased(KeyEvent e) {
		Object source = e.getSource();
		if (source.equals(nameField)) {
			checkName();
		} else if (source.equals(pwdConfirmField) || source.equals(pwdField)) {
			checkPassword();
		} else if (source.equals(emailField)) {
			checkEmail();
		}

		// Check values
		if (userNamePassed && pwdPassed && emailPassed) {
			createBtn.setEnabled(true);
		} else {
			createBtn.setEnabled(false);
		}
	}

	private void checkEmail() {
		Matcher matcher = emailPattern.matcher(emailField.getText());
		if (matcher.matches()) {
			errorMessage.setText("");
			emailPassed = true;
		} else {
			errorMessage.setText("Invalid email address!");
			emailPassed = false;
		}
	}

	private void checkPassword() {
		String pwd = new String(pwdField.getPassword());
		String confirmPwd = new String(pwdConfirmField.getPassword());
		// Compare password fields
		if (pwd.equals(confirmPwd)) {
			errorMessage.setText("");
			pwdPassed = true;
		} else {
			errorMessage.setText("Passwords do not match!");
			pwdPassed = false;
		}
	}

	private void checkName() {
		String userName = nameField.getText();
		// Make sure field isn't empty
		if (!userName.equals("")) {
			errorMessage.setText("");
			userNamePassed = true;
			// Check if user already exists
		} else {
			errorMessage.setText("Username cannot be empty!");
			userNamePassed = false;
		}
	}

	@Override
	public void keyTyped(KeyEvent e) {
		// Ignore this
	}

	@Override
	public String getTitle() {
		return "Welcome to Super Kids 123 Adventure!";
	}

	@Override
	public String getBorderTitle() {
		return "Initial Parent Setup";
	}

}
